package com.ebelter.btlibrary.btble.ble.bluetooth.device;


import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.os.ParcelUuid;

import com.ebelter.btlibrary.btble.ble.model.BleDevice;
import com.ebelter.btlibrary.btble.ble.model.BleType;
import com.ebelter.btlibrary.util.ULog;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 5.0以上scan和自动连接方式
 *
 * @author fenghui
 */
@SuppressLint("NewApi")
public class BtScanLollipopAndAutoGattListener extends BlueToothServer {

    private static final String TAG = "BtScanLollipopAndAutoGattListener";
    BluetoothLeScanner mBluetoothLeScanner = null;
    List<ScanFilter> bleScanFilters = null;
    ScanSettings bleScanSettings = null;
    boolean isNeedReconnect = false;

    public BtScanLollipopAndAutoGattListener(Context ctx) {
        super(ctx);

        //连接回调信息
        mGattCallback = new BluetoothGattCallback() {
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                mHandler.removeCallbacks(connectTimeoutThread);

                ULog.i(TAG, "onConnectionStateChange, status:" + status + ",new status:" + newState);

                if (status == BluetoothGatt.GATT_SUCCESS) {

                    if (newState == BluetoothProfile.STATE_CONNECTED) {
                        if (!isConnected) {
                            //连接状态改变为连接成功
                            mBluetoothGatt.discoverServices();
                        }
                    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                        if (isConnected) {
                            ULog.i(TAG, "device disconnected.");
                            isConnected = false;
                            lastRssi = 0;
                            if (mConnectCallback != null) {
                                mConnectCallback.onDisConnected();
//								deviceDataHandler.getMsgCallBack().onDisConnected();
                            }
                        }

                        if (isNeedReconnect) {
                            isNeedReconnect = false;
                            gatt.close();
                            if (isNeedConnecting) {
                                startScanDevice();
                            }
                        }
                    }
                } else {
                    ULog.e(TAG, "status is not 0. do close operate.");
                    gatt.close();
                    mBluetoothGatt = null;
                    isConnected = false;
                    if (isNeedConnecting) {
                        startScanDevice();
                    }
                }
            }

            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                ULog.w(TAG, "onServicesDiscovered received: " + status);
                if (status == BluetoothGatt.GATT_SUCCESS) {

                    //搜寻设备完毕，写入数据特征到设备中
                    isConnected = true;
                    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
                        ULog.e(TAG, "BluetoothAdapter not initialized");
                        return;
                    }

                    btService = mBluetoothGatt.getService(UUID.fromString(BluetoothUtil.getDeviceServiceUUID()));
                    if (btService == null) {
                        ULog.e(TAG, "service is null.");
                        //状态码出错，先断开连接然后再重新连接
                        gatt.disconnect();
                        gatt.close();
                        return;
                    }

                    //数据通知uuid列表
                    deviceReadNotifyUUIDs = BluetoothUtil.getReadUUIDs();
                    BluetoothGattCharacteristic characteristic = btService.getCharacteristic(UUID.fromString(deviceReadNotifyUUIDs[0]));
                    if (characteristic != null) {
                        mBluetoothGatt.setCharacteristicNotification(characteristic, true);
                        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(BluetoothUtil.CLIENT_CHARACTERISTIC_CONFIG));
                        if (descriptor != null) {
                            ULog.i(TAG, "mBluetoothGatt.writeDescriptor.");
                            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                            mBluetoothGatt.writeDescriptor(descriptor);
                        } else {
                            ULog.e(TAG, "descriptor is null.");
                        }
                        mBluetoothGatt.readCharacteristic(characteristic);
                    }

                } else {
                    //异常状态，比如129，需要重新连接设备
                    isNeedReconnect = true;
                    gatt.disconnect();
                }
            }


            public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor gattDescriptor, int status) {
                ULog.i(TAG, "onDescriptorWrite, status:" + status);
                if (status != 0) {
                    ULog.i(TAG, "onDescriptorWrite, status not 0, do disconnect.");
                    //状态码出错，先断开连接然后再重新连接
                    //异常状态，比如129，重启蓝牙
                    isNeedReconnect = true;
                    gatt.disconnect();
                } else {
                    //这里通知前端，设备连接成功
                    if (mConnectCallback != null) {
                        mConnectCallback.onConnected(gatt.getDevice());
//						deviceDataHandler.getMsgCallBack().onDeviceConnected();
                    }

                    connectTotal++;
                    ULog.i(TAG, "device connected times." + connectTotal
                            + ",isConnected:" + isConnected);

                    UUID uuid = gattDescriptor.getCharacteristic().getUuid();
                    //设置多通道通知
                    setMutiNotify(uuid, 1);
                    setMutiNotify(uuid, 2);
                    setMutiNotify(uuid, 3);

                    if (BleDevice.getInstance().getType() == BleType.OXIMETER) {
                        //血氧仪，监听4个通道通知，第4通道写入数据，开始接收通知
                        if (uuid.equals(UUID.fromString(deviceReadNotifyUUIDs[3]))) {
                            ULog.i(TAG, "-----onDescriptorWrite---characteristic_4----write data ");
                            //  broadcastUpdate(BleAction.ACTION_XUEYANG_WRITE);
                            byte[] bytes = {(byte) 0xaa, 0x55, 0x04, (byte) 0xb1, 0x00, 0x00, (byte) 0xb5};
                            writeLlsAlertLevel(bytes);
                        }
                    }
                }

            }

            ;

            @Override
            public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                //读取到数据
                ULog.i(TAG, "onCharacteristicRead");
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    ULog.i("TAG", Arrays.toString(characteristic.getValue()));
                }
            }

            /**
             * 返回数据。
             */
            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                currMutualTime = System.currentTimeMillis();
                ULog.i("onCharacteristicChanged---------", "isConnected:" + isConnected);
                if (!isConnected) {
                    ULog.e(TAG, "device not connected, return from onCharacteristicChanged.");
                    return;
                }
                if (mBleMessageAnalyser != null) {
                    onReceiveBleMessage(characteristic.getUuid().toString(), characteristic.getValue());
                }
            }
        };
    }


    //扫描设备
    @Override
    protected void scanLeDevice(boolean enable) {
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
            ULog.i(TAG, "mBluetoothAdapter.isEnabled：不能使用或者关闭了" );
            return;
        }

        if (mBluetoothLeScanner == null) {
            mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
            bleScanFilters = new ArrayList<ScanFilter>();
            ParcelUuid uuid = ParcelUuid.fromString(BluetoothUtil.getDeviceServiceUUID());
//		        bleScanFilters.add(
//		                new ScanFilter.Builder().setServiceUuid(uuid).build()
//		        );

            bleScanSettings = new ScanSettings.Builder().
                    setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                    .build();
        }
        ULog.i(TAG, "--------scanLeDevice----------enable = " + enable);
        if (enable) {
            ULog.d(TAG, "begin to scan bluetooth devices...");
            mScanning = true;
            try {
                //mBluetoothLeScanner.startScan(scanCallback);
                mBluetoothLeScanner.startScan(null, bleScanSettings, scanCallback);
            } catch (Exception e) {
                ULog.e(TAG, "startScan error." + e.getMessage());
            }
            //mBluetoothLeScanner.startScan(bleScanFilters, bleScanSettings, scanCallback);
        } else {
            ULog.d(TAG, "stop to scan bluetooth devices.");
            mScanning = false;
            try {
                mBluetoothLeScanner.stopScan(scanCallback);
            } catch (Exception e) {
                ULog.e(TAG, "stopScan error." + e.getMessage());
            }
        }
    }

    private ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(final int callbackType, final ScanResult result) {
            super.onScanResult(callbackType, result);

            ULog.i(TAG, "onScanResult. callbackType is :" + callbackType
                    + ",name:" + result.getDevice().getName()
                    + ",address:" + result.getDevice().getAddress()
                    + ",rssi:" + result.getRssi());

            if (result.getDevice().getName() == null ||
                    result.getDevice().getAddress() == null) {
                return;
            }

            String name = result.getDevice().getName();
            currDeviceType = BluetoothUtil.getDeviceTypeByDeviceName(name);
            ULog.d(TAG, "--------------onScanResult---------------name = " + name + ", currDeviceType = " + currDeviceType);
            if (currDeviceType > -1) {
                //只有未连接的时候才继续
                if (deviceConnectState != BluetoothProfile.STATE_DISCONNECTED) {
                    ULog.e(TAG, "deviceConnectState is：" + deviceConnectState);
                    return;
                }
                ULog.i(TAG, "found ch100 device!");
                //通知发现设备
                if (mScanResultCallback != null) {
                    mScanResultCallback.onDiscovered(result.getDevice());
//					deviceDataHandler.getMsgCallBack().onDiscovered(result.getDevice());
                }
            }
        }

        @Override
        public void onBatchScanResults(final List<ScanResult> results) {
            super.onBatchScanResults(results);
            ULog.i(TAG, "onBatchScanResults, results size:" + results.size());
            for (ScanResult item : results) {
                ULog.i(TAG, "result info :" + item.getDevice().getName() + ","
                        + "address:" + item.getDevice().getAddress() + ", rssi:"
                        + item.getRssi());

                currDeviceType = BluetoothUtil.getDeviceTypeByDeviceName(item.getDevice().getName());
                ULog.d(TAG, "--------------onBatchScanResults---------------name = " + item.getDevice().getName() + ", currDeviceType = " + currDeviceType);
                if (currDeviceType > -1) {
                    //只有未连接的时候才继续
                    if (deviceConnectState != BluetoothProfile.STATE_DISCONNECTED) {
                        ULog.e(TAG, "deviceConnectState is：" + deviceConnectState);
                        return;
                    }
                    ULog.i(TAG, "found target device!");
                    //通知发现设备
                    if (mScanResultCallback != null) {
                        mScanResultCallback.onDiscovered(item.getDevice());
//						deviceDataHandler.getMsgCallBack().onDiscovered(item.getDevice());
                    }
                }
            }
        }

        @Override
        public void onScanFailed(final int errorCode) {
            super.onScanFailed(errorCode);
            ULog.e(TAG, "onScanFailed, code is : " + errorCode);
//			try {
//				Thread.sleep(500);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
            //重启蓝牙
            //restartBluetooth();
        }
    };

    /**
     * 开始连接设备
     */
    @Override
    public void startConnectDevice(BluetoothDevice device) {
        isNeedConnecting = true;
        currConnectDevice = device;
//		deviceDataHandler.setDeviceAddress(device.getAddress());
        if (!isConnected) {
            mBluetoothGatt = currConnectDevice.connectGatt(mContext, true, mGattCallback);
            refreshDeviceCache(mBluetoothGatt);
        }
    }
}  